package vip.xiaonuo.modular.xyethnic.api;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import vip.xiaonuo.core.annotion.BusinessLog;
import vip.xiaonuo.core.annotion.Permission;
import vip.xiaonuo.core.annotion.version.ApiVersionSwagger;
import vip.xiaonuo.core.context.login.LoginContextHolder;
import vip.xiaonuo.core.enums.LogAnnotionOpTypeEnum;
import vip.xiaonuo.core.pojo.base.param.BaseParam;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.modular.xyethnic.entity.XyEthnic;
import vip.xiaonuo.modular.xyethnic.form.*;
import vip.xiaonuo.modular.xyethnic.param.XyEthnicParam;
import vip.xiaonuo.modular.xyethnic.service.XyEthnicService;
import vip.xiaonuo.modular.xyethnic.vo.*;
import vip.xiaonuo.modular.xylogy.entity.XyLogy;
import vip.xiaonuo.modular.xylogy.param.XyLogyParam;
import vip.xiaonuo.modular.xylogy.service.XyLogyService;
import vip.xiaonuo.modular.xylogylogs.service.XyLogyLogsService;
import vip.xiaonuo.modular.xyuser.entity.XyUser;
import vip.xiaonuo.modular.xyuser.service.XyUserService;
import vip.xiaonuo.sys.core.msg.Result;

import java.util.*;
import java.util.stream.Collectors;

import static vip.xiaonuo.modular.xyethnic.constant.EthnicConstant.OldDataConstant.OLD_DATA;
import static vip.xiaonuo.modular.xyethnic.constant.EthnicConstant.RelationshipConstant.sonLevel;
import static vip.xiaonuo.modular.xyethnic.constant.EthnicConstant.RelationshipConstant.sonfLevel;
import static vip.xiaonuo.sys.core.msg.ResultUtils.success;

@RestController
@Api(tags = "族员apis")
@ApiVersionSwagger
@RequestMapping("/ethnic")
@Slf4j
public class ApiEthnicController {

    @Autowired
    private XyEthnicService xyEthnicService;

    @Autowired
    private XyUserService xyUserService;

    @Autowired
    private XyLogyService xyLogyService;


    /**
     * 创建 或 更改族员
     */
    @PostMapping("/saveEthnic")
    @ApiOperation("创建族员")
    public Result saveEthnic(@RequestBody @Validated EthnicForm ethnicForm){
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        xyEthnicService.saveEthnic(ethnicForm,userId);
        return success();
    }

    /**
     * 分页查询当前族谱，协作者编辑的信息
     */
    /**
     * 查询族员
     *
     * @author yanwei
     * @date 2023-05-05 15:44:28
     */
    @GetMapping("/authEditEthnic/page")
    @ApiOperation("协作者审核族员列表_查询")
    public Result<PageResult<XyEthnic>> page( @Validated(XyEthnicParam.detail.class) XyEthnicParam xyEthnicParam) {
        xyEthnicParam.setOldDataId(null);
        PageResult<XyEthnic> page = xyEthnicService.page(xyEthnicParam);
        // 当标题展示
        List<XyEthnic> rows = page.getRows();
        for (XyEthnic row : rows) {
            DictEditStrVo dictStrVo = new DictEditStrVo();
            dictStrVo.setUpdateTime(row.getUpdateTime());
            dictStrVo.setCommName("协作者");
            dictStrVo.setFromTo(StrUtil.format("纠正了{}的个人信息",row.getName()));
            row.setDictEditStrVo(dictStrVo);
        }
        return success(page);
    }

    /**
     * 邀请用户来绑定对应的族员信息
     */
    @GetMapping("/pleaseBindEthnic/{ethnicId}")
    @ApiOperation(value = "邀请用户来绑定对应的族员信息",notes = "传入族员编号\r会已当前的用户进行绑定族员，等待审核!")
    public Result pleaseBindEthnic(@PathVariable String ethnicId){
        xyEthnicService.pleaseBindEthnic(ethnicId);
        return success();
    }

    /**
     * 邀请用户
     */
    @GetMapping("/pleaseNewBindEthnic/{ethnicId}/{userId}")
    @ApiOperation(value = "邀请用户")
    public Result pleaseNewBindEthnic(@PathVariable String ethnicId,@PathVariable String userId){
        xyEthnicService.pleaseNewBindEthnic(ethnicId,userId);
        return success();
    }

    /**
     * 请求前用户
     */
    @GetMapping("/bindEthnicAlter/{ethnicId}")
    @ApiOperation(value = "请求前用户邀请绑定列表")
    public Result<JSONObject> bindEthnicAlter(@PathVariable String ethnicId){
        JSONObject jsonObject = JSONObject.of("userId", LoginContextHolder.me().getSysLoginUser().getStrId(), "ethnicId", ethnicId);
        return success(jsonObject);
    }

    /**
     * 审核用户绑定族员列表_查询
     */
    @GetMapping("/bindEthnic/page")
    @ApiOperation("审核用户绑定族员列表_查询")
    public Result<PageResult<XyEthnic>> bindEthnicPage( @Validated(XyEthnicParam.detail.class) XyEthnicParam xyEthnicParam) {
        xyEthnicParam.setBindFlag(Objects.isNull(xyEthnicParam.getBindFlag()) ? -1  : xyEthnicParam.getBindFlag());
        XyLogy logy = xyLogyService.getById(xyEthnicParam.getLogyId());
        PageResult<XyEthnic> page = xyEthnicService.page(xyEthnicParam);
        // 当标题展示
        List<XyEthnic> rows = page.getRows();
        for (XyEthnic row : rows) {
            DictStrVo dictStrVo = new DictStrVo();
            dictStrVo.setUpdateTime(row.getUpdateTime());
            XyUser xyUser = xyUserService.getById(row.getUserId());
            if (Objects.nonNull(xyUser))
                dictStrVo.setCommName(xyUser.getNickName());
            else
                dictStrVo.setCommName("匿名用户");
            dictStrVo.setFromTo("通过管理员的绑定邀请");
            dictStrVo.setOverStr(StrUtil.format("申请加入:{}",logy.getLogyName()));
            row.setDictStrVo(dictStrVo);
        }
        return success(page);
    }

    /**
     * 审核用户绑定族员
     */
    @PostMapping("/bindEthnicChange")
    @ApiOperation("审核协作者用户绑定族员")
    public Result bindEthnicChange(@RequestBody @Validated AuthEditEthnicsForm authEditEthnicForm){
        xyEthnicService.bindEthnicChange(authEditEthnicForm);
        return success();
    }



    /**
     * 验证审核,
     */
    @PostMapping("/authEditChange")
    @ApiOperation("审核协作者族员修正列表的")
    public Result authEditChange(@RequestBody @Validated AuthEditEthnicForm authEditEthnicForm){
        xyEthnicService.authEditChange(authEditEthnicForm);
        return success();
    }


    /**
     * 编辑族员
     */
    @PostMapping("/chageEthnic")
    @ApiOperation(value = "编辑族员",notes = "后台会自动控制是否是有绝对权限的，还是没有权限的!")
    public Result chageEthnic(@RequestBody @Validated EthnicEditForm ethnicEditForm){
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        xyEthnicService.chageEthnic(ethnicEditForm,userId);
        return success();
    }



    /**
     * 查看族员信息
     */
    @GetMapping("/findEthnic/{id}")
    @ApiOperation(value = "查询族员信息",notes = "根据族员id查询详情")
    public Result<XyEthnic> findEthnic(@PathVariable String id){
        return success(xyEthnicService.getById(id));
    }

    /**
     * 统计项
     */
    @GetMapping("/countLogy/{id}")
    @ApiOperation(value = "统计当前族谱的 红丁，男丁，女丁，始祖是谁",notes = "组谱编号")
    public Result<CountLogyVo> countLogy(@PathVariable String id){
        return success(xyEthnicService.countLogy(id));
    }



    /**
     * 当前家谱的 世
     */
    @PostMapping("/logyLevels")
    @ApiOperation(value = "当前族谱的 世",notes = "已经排过序了,族谱编号,例如 第一世，第二世\r 并且只有 子女等直系")
    public Result<List<LevelsLogyVo>> logyLevels(@RequestBody EthnicTreeListForm ethnicTreeListForm){
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        List<LevelsLogyVo> levelsLogyVoList =   xyEthnicService.logyLevels(ethnicTreeListForm,userId);
        return success(levelsLogyVoList);
    }
    /**
     * 当前家谱的 世
     */
    @PostMapping("/selectLogyLevels")
    @ApiOperation(value = "当前族谱的 世选择框",notes = "已经排过序了,族谱编号,例如 第一世，第二世\r 并且只有 子女等直系")
    public Result<List<XyEthnic>> selectLogyLevels(@RequestBody EthnicTreeListForm ethnicTreeListForm){
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        List<LevelsLogyVo> levelsLogyVoList =   xyEthnicService.logyLevels(ethnicTreeListForm,userId);
        List<XyEthnic> leSel = Lists.newArrayList();
        for (LevelsLogyVo levelsLogyVo : levelsLogyVoList) {
            leSel.addAll(levelsLogyVo.getXyEthnics());
        }
        return success(leSel);
    }

    /**
     * 查看当前家谱信息
     */
    @PostMapping("/treeListData")
    @ApiOperation(value = "根据当前登录的用户,查看当前家谱的树形结构",notes = "族谱编号")
    public Result<TreeLogyVo> treeListData(@RequestBody EthnicTreeListForm ethnicTreeListForm){
        String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        TreeLogyVo treeLogyVo = xyEthnicService.treeListData(ethnicTreeListForm,userId);
        return success(treeLogyVo);
    }

    /**
     * 查看当前家谱信息
     */
    @PostMapping("/treeListDataTree")
    @ApiOperation(value = "根据当前登录的用户,查看当前家谱的树形结构",notes = "族谱编号")
    public Result< List<Tree<Object>>> treeListDataTree(@RequestBody EthnicTreeListForm ethnicTreeListForm){
        //String userId = LoginContextHolder.me().getSysLoginUser().getStrId();
        List<Tree<Object>> jsonObject = xyEthnicService.treeListDataTree(ethnicTreeListForm,null);
        return success(jsonObject);
    }

    /**
     * 行传列表
     */
    @GetMapping("/lineChildList/{logyId}")
    @ApiOperation(value = "行传列表",notes = "行传列表 数据结构 为列表，已经排过序")
    public Result<List<LineLevelsLogyVo>> lineChildList(@PathVariable String logyId){
        List<LineLevelsLogyVo> lineLevelsLogyVos =  xyEthnicService.lineChildList(logyId);
        return success(lineLevelsLogyVos);
    }


    /**
     * 行传列表
     */
    @GetMapping("/lineChildListOld/{logyId}")
    @ApiOperation(value = "行传列表Old",notes = "行传列表 数据结构 为列表，已经排过序")
    public Result<List<ListEthnicVo>> lineChildListOld(@PathVariable String logyId){
        List<ListEthnicVo> lineLevelsLogyVos =  xyEthnicService.lineChildListOld(logyId);
        return success(lineLevelsLogyVos);
    }

    /**
     * 左右切换位置
     */
    @GetMapping("/chagePoiEthnic/{poi}/{id}")
    @ApiOperation(value = "左右切换族员位置,poi = 1 左，poi=2 右；id族员编号",notes = "必须是主分支才可以")
    public Result chagePoiEthnic(@PathVariable Integer poi,@PathVariable String id){
        try {
            xyEthnicService.chagePoiEthnic(poi,id);
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return success();
    }

    /**
     * 向上切换位置
     */
    @GetMapping("/upChagePoi/{upId}/{id}")
    @ApiOperation("向上切换位置,upId 是选择框的ID,id 是 当前族员的ID")
    public Result upChagePoi(@PathVariable String upId,@PathVariable String id){
        xyEthnicService.upChagePoi(upId,id);
        return success();
    }

    /**
     * 当前族员节点 上层的信息
     */
    @GetMapping("/findLevelsSelect/{id}")
    @ApiOperation("根据当前节点查询像上转移的选择框,当前族员的编号")
    public Result<List<DictLevelStrVo>> findLevelsSelect(@PathVariable String id){
        return success(xyEthnicService.findLevelsSelect(id));
    }

    /**
     * 删除当前族员
     */
    @GetMapping("/del/{id}")
    @ApiOperation("删除当前族员")
    public Result del(@PathVariable String id){
        xyEthnicService.del(id);
        return success();
    }

    /**
     * 根据家谱编号查询出来人最多的人
     */
    @GetMapping("/logyIdByLevel/{logyId}")
    @ApiOperation("根据家谱编号查询出来人最多的人")
    public Result logyIdByLevel(@PathVariable String logyId){
        List<XyEthnic> xyEthnicList = xyEthnicService.list(Wrappers.<XyEthnic>lambdaQuery().eq(XyEthnic::getLogyId, logyId));
        Map<Integer, List<XyEthnic>> integerListMap = xyEthnicList.stream().collect(Collectors.groupingBy(XyEthnic::getLevels));
        Collection<List<XyEthnic>> values = integerListMap.values();
        // 那个size 最大
        Integer integer = 0;

        List<List<XyEthnic>> collect1 = values.stream().sorted(Comparator.comparing(List::size)).collect(Collectors.toList());
        if (!collect1.isEmpty()){
            List<XyEthnic> xyEthnics = collect1.get(collect1.size() - 1);
            for (XyEthnic xyEthnic : xyEthnics) {
                if (sonfLevel.contains(xyEthnic.getRelationship())) {
                    // 都是主分支
                    // 有没有配偶?
                    long count = xyEthnics.stream().filter(item -> xyEthnic.getId().equals(item.getIsJoin())).count();
                    integer = (Math.toIntExact((count + 1) * 200) + 34) + integer;
                }

            }
        }

        return success(integer);
    }








}
